package com.caregiver.watch.business.user.service.impl;

import com.caregiver.watch.business.care.model.dto.UpdateCareRecipientParam;
import com.caregiver.watch.business.user.dao.UserDeviceDao;
import com.caregiver.watch.business.user.enums.CareRelationshipEnum;
import com.caregiver.watch.business.user.helper.CareRecipientHelper;
import com.caregiver.watch.business.user.model.dto.AddContactDeviceParam;
import com.caregiver.watch.business.user.model.dto.EditContactDeviceParam;
import com.caregiver.watch.business.user.model.po.UserCareRecipient;
import com.caregiver.watch.business.user.model.po.UserDevice;
import com.caregiver.watch.business.user.model.vo.ContactDeviceDetailVo;
import com.caregiver.watch.business.user.model.vo.UserDeviceVo;
import com.caregiver.watch.business.care.service.CareRecipientService;
import com.caregiver.watch.business.user.service.UserDeviceService;
import com.caregiver.watch.business.user.utils.UserInfoUtils;
import com.caregiver.watch.common.constant.NumberConstants;
import com.caregiver.watch.common.exception.business.BusinessException;
import com.caregiver.watch.common.helper.TransactionalHelper;
import com.caregiver.watch.common.utils.collection.ListUtils;
import com.caregiver.watch.common.utils.number.IntegerUtils;
import java.time.Period;
import com.caregiver.watch.thirdparty.service.DeviceSettingService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.caregiver.watch.business.user.helper.CareRecipientHelper.calculateAge;
import static com.caregiver.watch.common.constant.NumberConstants.ZERO;

/**
 * @Description: 用户设备服务
 * @Author 疆戟
 * @Date 2025/8/16 13:46
 * @Version 1.0
 */
@AllArgsConstructor
@Service
@Slf4j
public class UserDeviceServiceImpl implements UserDeviceService {

    private final UserDeviceDao userDeviceDao;
    private final CareRecipientService careRecipientService;
    private final TransactionalHelper transactionalHelper;
    private final CareRecipientHelper careRecipientHelper;
    private final DeviceSettingService deviceSettingService;


    @Override
    public void batchInsertUserDevice(Long userId, List<String> deviceUuids) {
        if (CollectionUtils.isEmpty(deviceUuids)) {
            return;
        }
        LocalDateTime now = LocalDateTime.now();
        List<UserDevice> userDevices = ListUtils.map(deviceUuids, deviceUuid -> {
            UserDevice userDevice = new UserDevice();
            userDevice.setUserId(userId);
            userDevice.setDeviceUuid(deviceUuid);
            userDevice.setCreateTime(now);
            userDevice.setUpdateTime(now);
            return userDevice;
        });
        try {
            userDeviceDao.batchInsertUserDevice(userDevices);
        } catch (Exception e) {
            log.error("批量插入用户设备异常", e);
        }
    }

    @Override
    public List<UserDeviceVo> queryUserDeviceList() {
        Long userId = UserInfoUtils.getUserId();
        // 查询用户设备
        List<UserDevice> userDevices = userDeviceDao.selectUserDeviceByUserId(userId);
        // 获取被照护人ID
        List<Long> recipientIds = ListUtils.mapDistinct(userDevices, UserDevice::getRecipientId);
        log.info("查询用户设备，被照护人ID:{}", recipientIds);
        List<UserCareRecipient> userCareRecipients = careRecipientService.queryUserCareRecipientByIds(userId, recipientIds);
        Map<Long, UserCareRecipient> recipientIdToUserCareRecipientMapping = ListUtils.toMap(userCareRecipients, UserCareRecipient::getRecipientId);
        log.info("查询用户设备，被照护人信息:{}", recipientIdToUserCareRecipientMapping);
        return ListUtils.map(userDevices, userDevice -> {
            UserCareRecipient userCareRecipient = recipientIdToUserCareRecipientMapping.get(userDevice.getRecipientId());
            String recipientAvatar = careRecipientHelper.getRecipientAvatar(userCareRecipient.getRelationship());
            return UserDeviceVo.build(userDevice, recipientIdToUserCareRecipientMapping.get(userDevice.getRecipientId()), recipientAvatar);
        });
    }

    @Override
    public Boolean addContactDevice(AddContactDeviceParam param) {
        if (StringUtils.isBlank(param.getDeviceName())) {
            throw new BusinessException("设备名称不能为空");
        }
        if (StringUtils.isBlank(param.getDeviceUuid())) {
            throw new BusinessException("设备UUID不能为空");
        }
        if (StringUtils.isBlank(param.getRecipientName())) {
            throw new BusinessException("被照护人姓名不能为空");
        }
        CareRelationshipEnum relationship = param.getRelationship();
        if (Objects.isNull(relationship)) {
            throw new BusinessException("关系不能为空");
        }
        if (Objects.isNull(param.getBirthday())) {
            throw new BusinessException("生日不能为空");
        }
        Long userId = UserInfoUtils.getUserId();
        UserCareRecipient userCareRecipient = param.buildUserCareRecipient(userId);
        Boolean success = transactionalHelper.execute(() -> {
            Long recipientId = careRecipientService.insertUserCareRecipient(userCareRecipient);
            if (Objects.isNull(recipientId)) {
                throw new BusinessException("添加被照护人失败");
            }
            UserDevice userDevice = param.buildUserDevice(userId, recipientId);
            try {
                return userDeviceDao.insertUserDevice(userDevice) > ZERO;
            } catch (DuplicateKeyException e) {
                log.error("设备UUID:{}已存在", param.getDeviceUuid(), e);
                throw new BusinessException("设备UUID:" + param.getDeviceUuid() + "已存在");
            } catch (Exception e) {
                log.error("添加用户设备异常", e);
                throw new BusinessException("添加用户设备异常");
            }
        });
        if (BooleanUtils.isTrue(success)) {
            // 开启上传定位
            Boolean setAutoLocation = deviceSettingService.setAutoLocationInterval(param.getDeviceUuid(), true, NumberConstants.FIVE);
            log.info("设置数据上传自动定位间隔:{}自动定位:{}", param.getDeviceUuid(), setAutoLocation);
            // 用生日计算出年龄
            int age = calculateAge(param.getBirthday());
            // 设置照护人信息
            Boolean setUserInfo = deviceSettingService.setUserInfo(param.getDeviceUuid(),
                            param.getHeight(),
                            param.getWeight(),
                            param.getGender(),
                            age,
                            param.getWristCircumference());
            log.info("设置照护人信息:{}", setUserInfo);
        }
        return success;
    }


    @Override
    public Boolean deleteContactDevice(Long deviceId) {
        if (Objects.isNull(deviceId)) {
            throw new BusinessException("请选择要删除的设备");
        }
        Long userId = UserInfoUtils.getUserId();
        // 查询设备信息
        UserDevice userDevice = userDeviceDao.selectUserDeviceById(deviceId, userId);
        if (Objects.isNull(userDevice)) {
            throw new BusinessException("设备不存在");
        }
        // 删除照护人信息
        Long recipientId = userDevice.getRecipientId();
        if (Objects.nonNull(recipientId)) {
            careRecipientService.deleteCareRecipient(recipientId);
        }
        return userDeviceDao.deleteUserDeviceById(deviceId , userId) > ZERO;
    }

    @Override
    public List<UserDevice> queryDeviceUuIds(String lastDeviceUuId, Integer limit) {
        return userDeviceDao.queryDeviceUuIds(limit, lastDeviceUuId);
    }

    @Override
    public Long queryUserIdByDeviceUuid(String deviceUuid) {
        if (StringUtils.isBlank(deviceUuid)) {
            return null;
        }
        return userDeviceDao.selectUserIdByDeviceUuid(deviceUuid);
    }

    @Override
    public Long queryDeviceIdByDeviceUuid(String deviceUuid) {
        if (StringUtils.isBlank(deviceUuid)) {
            return null;
        }
        return userDeviceDao.selectUserDeviceIdByUuid(deviceUuid);
    }

    @Override
    public Boolean updateUserDevice(UserDevice userDevice) {
        if (Objects.isNull(userDevice)) {
            return false;
        }
        return userDeviceDao.updateUserDevice(userDevice) > ZERO;
    }

    @Override
    public Boolean updateBatteryAndRssi(Long userId, String deviceUuid, Integer batteryLevel, Integer rssi) {
        return userDeviceDao.updateBatteryAndRssi(userId, deviceUuid, batteryLevel, rssi) > ZERO;
    }

    @Override
    public ContactDeviceDetailVo queryContactDeviceDetail(Long deviceId) {
        Long userId = UserInfoUtils.getUserId();
        UserDevice userDevice = userDeviceDao.selectUserDeviceById(deviceId, userId);
        log.info("查询用户设备详情，设备:{}", userDevice);
        if (Objects.isNull(userDevice)) {
            throw new BusinessException("设备不存在");
        }
        ContactDeviceDetailVo contactDeviceDetailVo = ContactDeviceDetailVo.build(userDevice);
        Long recipientId = userDevice.getRecipientId();
        log.info("查询用户设备详情，被照护人ID:{}", recipientId);
        if (Objects.isNull(recipientId)) {
            return contactDeviceDetailVo;
        }
        UserCareRecipient userCareRecipient = careRecipientService.selectUserCareRecipientById(userId, recipientId);
        if(Objects.isNull(userCareRecipient)) {
            return contactDeviceDetailVo;
        }
        log.info("查询用户设备详情，被照护人信息:{}", userCareRecipient);
        contactDeviceDetailVo.setUserCareRecipient(userCareRecipient);
        return contactDeviceDetailVo;
    }

    @Override
    public UserCareRecipient queryContactDeviceDetail(Long userId, String deviceUuid) {
        if (Objects.isNull(userId)) {
            return null;
        }
        if (StringUtils.isBlank(deviceUuid)) {
            return null;
        }
        UserDevice userDevice = userDeviceDao.queryDeviceByUuId(userId, deviceUuid);
        log.info("查询用户设备详情，设备:{}", userDevice);
        if (Objects.isNull(userDevice)) {
            throw new BusinessException("设备不存在");
        }
        Long recipientId = userDevice.getRecipientId();
        log.info("查询用户设备详情，被照护人ID:{}", recipientId);
        if (Objects.isNull(recipientId)) {
            return null;
        }
        return careRecipientService.selectUserCareRecipientById(userId, recipientId);
    }

    @Override
    public List<UserDevice> queryAllContactDeviceList(Long userId) {
        if (Objects.isNull(userId)) {
            return new ArrayList<>();
        }
        return userDeviceDao.queryAllContactDeviceList(userId);
    }

    @Override
    public Boolean checkDevicePermission(Long userId, String deviceUuid) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return false;
        }
        return IntegerUtils.isPositive(userDeviceDao.checkDevicePermission(userId, deviceUuid));
    }

    @Override
    public Boolean editContactDevice(EditContactDeviceParam param) {
        Long userId = UserInfoUtils.getUserId();
        Long deviceId = param.getDeviceId();
        // 如果传了设备
        if (Objects.nonNull(deviceId)) {
            // 设备名称不为空
            if (StringUtils.isBlank(param.getDeviceName())) {
                throw new BusinessException("设备名称不能为空");
            }
            UserDevice userDevice = new UserDevice();
            userDevice.setDeviceId(deviceId);
            userDevice.setDeviceName(param.getDeviceName());
            // 跟新设备名称
            boolean success = userDeviceDao.updateUserDeviceName(deviceId, userId, param.getDeviceName()) > ZERO;
            log.info("更新设备名称，结果:{}", success);
        }
        Long recipientId = param.getRecipientId();
        if (Objects.nonNull(recipientId)) {
            UpdateCareRecipientParam updateParam = new UpdateCareRecipientParam();
            updateParam.setRecipientId(recipientId);
            updateParam.setRecipientName(param.getRecipientName());
            updateParam.setRelationship(param.getRelationship());
            updateParam.setGender(param.getGender());
            updateParam.setBirthday(param.getBirthday());
            updateParam.setWristCircumference(param.getWristCircumference());
            updateParam.setHeight(param.getHeight());
            updateParam.setWeight(param.getWeight());
            Boolean success = careRecipientService.updateCareRecipient(updateParam);
            log.info("更新被照护人信息，结果:{}", success);
        }
        return Boolean.TRUE;
    }
}
